package com.tpp.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.tpp.pojo.baseVo.BaseResult;
import com.tpp.pojo.resp.MovieResp;
import com.tpp.service.EduSearchService;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Package: com.myh.service.impl
 * @ClassName: EduSearchServiceImpl
 * @Author: myh
 * @CreateTime: 2021/8/28 12:03
 * @Description:
 */

@Service
public class EduSearchServiceImpl implements EduSearchService {

    @Autowired
    RestHighLevelClient client;


    @Override
    public BaseResult search(String key, Integer page, Integer size) {

//        1、声明搜索对象（索引库）
        SearchRequest searchRequest = new SearchRequest("es_movie");
//        2、搜索源对象构建
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        if(StringUtils.isEmpty(key)){
            MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
            searchSourceBuilder.query(matchAllQueryBuilder); //这个是搜索全部
        }else {
            MultiMatchQueryBuilder field = QueryBuilders.multiMatchQuery(key, "movieName", "movieType").field("movieName", 10);
            searchSourceBuilder.query(field);  //这个是用关键词匹配多个字段，同时field可以提升当前关键字的得分。
        }

//        3、设置分页
        Integer from=(page-1)*size;
        searchSourceBuilder.from(from);
        searchSourceBuilder.size(size);

//        4、设置高亮,先new一个highliBuilder
        HighlightBuilder highlightBuilder = new HighlightBuilder();
//            4.1设置开头
        highlightBuilder.preTags("<font style='color:red'>");
//            4.2设置结尾
        highlightBuilder.postTags("</font>");
//            4.3设置高亮字段
        highlightBuilder.field("movieName");
        highlightBuilder.field("movieType");

//            4.4将高亮设置到搜索元中
        searchSourceBuilder.highlighter(highlightBuilder);

//        5、将搜索元对象设置到请求对象中
        searchRequest.source(searchSourceBuilder);

//        6、开始设置高亮显示的返回值结果,这里直接捕获异常
        try{
            BaseResult baseResult = new BaseResult();

//            6.1 使用resthignlevelClient 发起搜索请求（这里捕获异常）
            SearchResponse search = client.search(searchRequest);

//            6.2 解析返回值
            SearchHits hits = search.getHits();
            long totalHits = hits.getTotalHits();
            System.out.println("当前数组的总数为"+totalHits);

            baseResult.setCount(totalHits);
            SearchHit[] hits1 = hits.getHits();
            List list = new ArrayList<>();

//            6.3 开始设置高亮显示后的返回值结果
            for(SearchHit hi: hits1){
//                6.3.1 获取高亮字段
                Map<String, HighlightField> highlightFields = hi.getHighlightFields();
                Map<String, Object> sourceAsMap = hi.getSourceAsMap();

//                6.3.2
                if (highlightFields!=null){
                    HighlightField movieName = highlightFields.get("movieName");
                    HighlightField movieType = highlightFields.get("movieType");

                    if(movieName!=null){
                        Text[] fragments = movieName.getFragments();
                        StringBuffer stringBuffer = new StringBuffer();

                        for(Text te:fragments){
                            stringBuffer.append(te);
                        }
                        sourceAsMap.put("movieName",stringBuffer);
                    }


                    if(movieType!=null){
                        Text[] fragments = movieType.getFragments();
                        StringBuffer stringBuffer = new StringBuffer();

                        for(Text te:fragments){
                            stringBuffer.append(te);
                        }
                        sourceAsMap.put("movieType",stringBuffer);
                    }
                }

//                开始把json格式的map对象转换为json格式的字符串
                String s = JSONObject.toJSONString(sourceAsMap);
//                把json格式的字符串解析为实体类对象
                MovieResp movieResp = JSONObject.parseObject(s, MovieResp.class);
//                把得到的实体类对象添加到集合中
                list.add(movieResp);
            }

            baseResult.setCode(0);
            baseResult.setMsg("查询成功");
            baseResult.setData(list);

            return baseResult;


        } catch (IOException exception) {
            exception.printStackTrace();
        }
        return new BaseResult(1,"查询失败");
    }
}
